package com.shinhye.demoproject.view;

import android.content.Context;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.ListView;
import android.widget.Scroller;

import com.shinhye.demoproject.util.WLog;

/**
 * 向下拖动展示第二页，在第二页向上拖动，展示第一页内容
 *
 * @author wl
 * @since 2015/12/8 13:55
 */
public class DragPageView extends ViewGroup {
	public static final int TYPE_NORMAL = 0;
	public static final int TYPE_LISTVIEW = 1;
	public static final int TYPE_WEBVIEW = 2;
	public static final int TYPE_SCROLLVIEW = 3;
    private int downHeight = 0;

	private boolean isOpen = false; // true:打开了第二页
	private OnScrollChangedListener onScrollChangedListener;// 滚动监听接口
	private View view1;
	private View view2;
    private Scroller mScroller;

    public DragPageView(Context context) {
		this(context, null);
	}
	
	public DragPageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
	}
	
	public DragPageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
	}

    public void init() {
        mScroller = new Scroller(getContext());
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        view1 = getChildAt(0);
        view2 = getChildAt(1);

        view1.setOnTouchListener(new MyTouchListener(TYPE_NORMAL));
        view2.setOnTouchListener(new MyTouchListener(TYPE_NORMAL));
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if(downHeight == 0)
            downHeight = b;
        view1.layout(l, t, r, b);
        view2.layout(l, b, r, b * 2);
    }

    @Override
	public boolean onTouchEvent(MotionEvent ev) { // 屏蔽touch事件,才能在监听其子控件的touch事件

		return false;
	}

//	@Override
//	public boolean onInterceptTouchEvent(MotionEvent event) {  // 屏蔽touch事件传递,才能在监听其子控件的touch事件
//        super.onInterceptTouchEvent(event);
//        //关闭键盘
//        InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
//        imm.hideSoftInputFromWindow(getWindowToken(), 0);
//        return false;
//    }
	
	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		super.onScrollChanged(l, t, oldl, oldt);
		if(onScrollChangedListener != null) {
			onScrollChangedListener.onScrollChanged(l, t, oldl, oldt, downHeight);
		}
	}
    @Override
    public void computeScroll() {
        // 如果返回true，表示动画还没有结束
        // 因为前面startScroll，所以只有在startScroll完成时 才会为false
        if (mScroller.computeScrollOffset()) {
            // 产生了动画效果，根据当前值 每次滚动一点
            scrollTo(mScroller.getCurrX(), mScroller.getCurrY());

            //此时同样也需要刷新View ，否则效果可能有误差
            postInvalidate();
        }
    }


    /**
     * 设置下拉显示第二页，要滚动的距离
     * @param downHeight
     */
    public void setDragDownHeight(int downHeight) {
        this.downHeight = downHeight;
    }

	// 滚动事件监听，获取滚动的距离，用户处理一些其他事
	public interface OnScrollChangedListener {
		void onScrollChanged(int l, int t, int oldl, int oldt, int total);
	}
	
	public void setOnScrollChangedListeneer(OnScrollChangedListener onScrollChangedListener) {
		this.onScrollChangedListener = onScrollChangedListener;
	}

	public class MyTouchListener implements OnTouchListener {
		private int offsetsum = 0;// 总的手指滑动距离
		private Point point = new Point();
		private int type = 0;
		private boolean touchToHandle = true;
		private boolean touchHandled = false;
		
		/**
		 * 使用 {@link DragPageView#TYPE_NORMAL} 、{@link DragPageView#TYPE_LISTVIEW} 、{@link DragPageView#TYPE_SCROLLVIEW} 、{@link DragPageView#TYPE_WEBVIEW}
		 * @param type type
		 */
		public MyTouchListener(int type) {
			this.type = type;
		}

		@Override
		public boolean onTouch(View v, MotionEvent event) {
//            //不允许拦截
//            v.getParent().requestDisallowInterceptTouchEvent(true);

            WLog.i("onTouch", "v=" + v.getClass().getSimpleName() + ";event=" + event.getAction() + ";touchToHandle=" + touchToHandle);
			
			//此处判断是否处于 顶部 位置，如果不处于顶部，则不交给listner处理事件
			switch (type) {
			case TYPE_LISTVIEW:
				ListView lv = (ListView) v;
				if(!isListViewOnTop(lv)) { //ListView没有滑到顶部
					touchToHandle = false;
					return false;
				}
				break;
				
			case TYPE_SCROLLVIEW:
			case TYPE_WEBVIEW:
				if(v.getScrollY() != 0) { //ScrollView、WebView不在顶部
					touchToHandle = false;
                    return false;
				}
				break;
			}
			
			int action = event.getAction();
			int offsety;
			int y;
			switch (action) {
			case MotionEvent.ACTION_DOWN:
				point.y = (int) event.getRawY();
				offsetsum = 0;
				touchToHandle = true;
				touchHandled = false;
				
				//down事件必须返回false，否则无法交给view本身的onTouchEvent执行。
				switch (type) {
				case TYPE_LISTVIEW:
				case TYPE_SCROLLVIEW:
				case TYPE_WEBVIEW:
					return false;
				}
				break;
				
			case MotionEvent.ACTION_MOVE:
				if(!touchToHandle)
					return false;
				
				y = (int) event.getRawY();
				offsety = y - point.y;
				offsetsum += offsety;
				
				//如果已经在执行touchListener了。不再分给其他view处理
				if(!touchHandled) {
					//如果正在向上拖动，则不需要交给listener处理。
					switch (type) {
					case TYPE_LISTVIEW:
					case TYPE_SCROLLVIEW:
					case TYPE_WEBVIEW:
						if(offsety < 0) {
							touchToHandle = false;
							return false;
						}
						break;
					}
				}
				
				point.y = (int) event.getRawY();
				scrollBy(0, -offsety / 3);
				touchHandled = true;
				break;
				
			case MotionEvent.ACTION_CANCEL:
			case MotionEvent.ACTION_UP:
				if(!touchToHandle)
					return false;
				if (offsetsum > 0) {// offsetsum大于0时是往下拉，只有当显示详情页是下拉才有效果，所以这里先判断isOpen的值。
					if (isOpen) {
						if (offsetsum > 300) {
							smoothScrollTo(0, 0);
							isOpen = false;
						} else {
							smoothScrollTo(0, downHeight);
							isOpen = true;
						}
					}
					else {
						smoothScrollTo(0, 0);
						isOpen = false;
					}
				} else {// offsetsum小于0时是往上拉，只有当隐藏详情页是下拉才有效果，所以这里先判断isOpen的值。
					if(!isOpen) {
						if (offsetsum < -300) {
							smoothScrollTo(0, downHeight);
							isOpen = true;
						} else {
							smoothScrollTo(0, 0);
							isOpen = false;
						}
					}
					else {
						smoothScrollTo(0, downHeight);
						isOpen = true;
					}
					
				}
                //up事件必须返回false，否则无法交给view本身的onTouchEvent执行。
                switch (type) {
                    case TYPE_LISTVIEW:
                    case TYPE_SCROLLVIEW:
                    case TYPE_WEBVIEW:
                        return false;
                }
				break;
			}
			return true;
		}
	}

    private void smoothScrollTo(int finX, int finY) {
        mScroller.startScroll(getScrollX(), getScrollY(), finX, finY);
        invalidate();
    }

    /**
     * 判断ListView是否在顶部
     * 
     * @return true-在顶部，否则false
     */
    private boolean isListViewOnTop(ListView lv) {
        final Adapter adapter = lv.getAdapter();

        if (null == adapter || adapter.isEmpty()) {
            return true;
        }
        
        int mostTop = (lv.getChildCount() > 0) ? lv.getChildAt(0).getTop() : 0;
        if (lv.getChildCount() == 0) {
            return true;
        } else if(lv.getFirstVisiblePosition() == 0) {
        	return mostTop >= 0;
        }

        return false;
    }
}
